home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / basic / _tree_collect.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  12.2 KB  |  580 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _tree_collect.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15.  
  16. // dyna_trees.c
  17.  
  18. #include <LEDA/tree_collection.h>
  19.  
  20. #define BIG MAXFLOAT
  21.  
  22.  
  23. void dyna_trees::splay(d_vertex x) {
  24.      d_vertex y, z, zz, a, b, c, d;
  25.      double   mincost_a,
  26.           mincost_b,
  27.           mincost_c,
  28.           mincost_d,
  29.           mincost_x,
  30.           mincost_y,
  31.           mincost_z,
  32.           
  33.           cost_x,
  34.           cost_y,
  35.           cost_z;
  36.  
  37.      
  38.      while (x->parent) {
  39.       // splay-step : 
  40.  
  41.       y=x->parent; // Vater von x
  42.       z=y->parent; // Grossvater von x (oder 0)
  43.       zz = (z==0) ? 0 : z->parent; // Urgrossvater von z (oder 0)
  44.  
  45.       // 1.Fall: x hat Vater, aber keinen Grossvater
  46.  
  47.       if (z==0){ 
  48.         if (y->left==x) { 
  49.             // x wurzel des linken unterbaums  (1)
  50.             a=x->left;
  51.             b=x->right;
  52.             c=y->right;
  53.             x->parent=0;
  54.             x->right=y;
  55.             y->parent=x;
  56.             y->left=b;
  57.             if (b) b->parent=y;
  58.  
  59.             x->successor=y->successor;
  60.             y->successor=0;
  61.  
  62.             mincost_a = (a) ? a->dmin + x->dmin + y->dmin : BIG;
  63.             mincost_b = (b) ? b->dmin + x->dmin + y->dmin : BIG;
  64.             mincost_c = (c) ? c->dmin + y->dmin : BIG;
  65.             mincost_x = x->dmin + y->dmin;
  66.             mincost_y = y->dmin;
  67.             cost_x    = x->dcost + mincost_x;
  68.             cost_y    = y->dcost + mincost_y;
  69.             
  70.             mincost_x = mincost_y;
  71.             mincost_y = (mincost_b <= mincost_c) ? mincost_b : mincost_c;
  72.             if (cost_y <= mincost_y) mincost_y = cost_y;
  73.             x->dcost = cost_x - mincost_x;
  74.             y->dcost = cost_y - mincost_y;
  75.             x->dmin  = mincost_x;
  76.             y->dmin  = mincost_y - mincost_x;
  77.             if (a) a->dmin  = mincost_a - mincost_x;
  78.             if (b) b->dmin  = mincost_b - mincost_y;
  79.             if (c) c->dmin  = mincost_c - mincost_y;
  80.         }
  81.         else {
  82.             // x wurzel des rechten unterbaums (2)
  83.             a=y->left;
  84.             b=x->left;
  85.             c=x->right;
  86.             x->parent=0;
  87.             x->left=y;
  88.             y->parent=x;
  89.             y->right=b;
  90.             if (b) b->parent=y;
  91.             
  92.             x->successor=y->successor;
  93.             y->successor=0;
  94.             
  95.             mincost_a = (a) ? a->dmin + y->dmin : BIG;
  96.             mincost_b = (b) ? b->dmin + x->dmin + y->dmin : BIG;
  97.             mincost_c = (c) ? c->dmin + x->dmin + y->dmin : BIG;
  98.             mincost_x = x->dmin + y->dmin;
  99.             mincost_y = y->dmin;
  100.             cost_x    = x->dcost + mincost_x;
  101.             cost_y    = y->dcost + mincost_y;
  102.             
  103.             mincost_x = mincost_y;
  104.             mincost_y = (mincost_a <= mincost_b) ? mincost_a : mincost_b;
  105.             if (cost_y <= mincost_y) mincost_y = cost_y;
  106.             x->dcost = cost_x - mincost_x;
  107.             y->dcost = cost_y - mincost_y;
  108.             x->dmin  = mincost_x;
  109.             y->dmin  = mincost_y - mincost_x;
  110.             if (a) a->dmin  = mincost_a - mincost_y;
  111.             if (b) b->dmin  = mincost_b - mincost_y;
  112.             if (c) c->dmin  = mincost_c - mincost_x;           
  113.         }
  114.         continue;
  115.       }
  116.  
  117.       
  118.       // 2.Fall: x hat also Grossvater, x und parGenPtr(x) linke (rechte)
  119.       //           Soehne.
  120.       // Linke Soehne:
  121.  
  122.       if ((z->left==y)&&(y->left==x)){   //  (3)
  123.         a=x->left;
  124.         b=x->right;
  125.         c=y->right;
  126.         d=z->right;
  127.         y->left=b;
  128.         if (b) b->parent=y;
  129.         z->left=c;
  130.         if (c) c->parent=z;
  131.         x->right=y;
  132.         y->parent=x;
  133.         y->right=z;
  134.         z->parent=y;
  135.         if (zz) {
  136.             if (zz->left==z){
  137.              zz->left=x;
  138.             }
  139.             else{
  140.              zz->right=x;
  141.             }
  142.         }
  143.         else {     //  z is solid-tree-root
  144.             x->successor=z->successor;    
  145.             z->successor=0;
  146.         } 
  147.         x->parent=zz;
  148.         
  149.         mincost_a = (a) ? a->dmin + x->dmin + y->dmin + z->dmin : BIG;
  150.         mincost_b = (b) ? b->dmin + x->dmin + y->dmin + z->dmin : BIG;
  151.         mincost_c = (c) ? c->dmin + y->dmin + z->dmin : BIG;
  152.         mincost_d = (d) ? d->dmin + z->dmin : BIG;
  153.         mincost_x =     x->dmin + y->dmin + z->dmin;
  154.         mincost_y =     y->dmin + z->dmin;
  155.         mincost_z =     z->dmin;
  156.         cost_x     = mincost_x + x->dcost;
  157.         cost_y     = mincost_y + y->dcost;
  158.         cost_z     = mincost_z + z->dcost;
  159.         
  160.         mincost_x = mincost_z;
  161.         mincost_z = (mincost_c <= mincost_d) ? mincost_c : mincost_d;
  162.         if (cost_z <= mincost_z) mincost_z = cost_z;
  163.         mincost_y = (mincost_b <= mincost_z) ? mincost_b : mincost_z;
  164.         if (cost_y <= mincost_y) mincost_y = cost_y;
  165.         x->dcost = cost_x - mincost_x;
  166.         y->dcost = cost_y - mincost_y;
  167.         z->dcost = cost_z - mincost_z;
  168.         x->dmin = mincost_x;
  169.         y->dmin = mincost_y - mincost_x;
  170.         z->dmin = mincost_z - mincost_y;
  171.         if (a) a->dmin    = mincost_a - mincost_x;
  172.         if (b) b->dmin    = mincost_b - mincost_y;
  173.         if (c) c->dmin    = mincost_c - mincost_z;
  174.         if (d) d->dmin    = mincost_d - mincost_z;
  175.  
  176.         continue;
  177.       }
  178.  
  179.       
  180.       // Rechte Soehne:   (4)
  181.       
  182.       if ((z->right==y)&&(y->right==x)){
  183.         a=z->left;
  184.         b=y->left;
  185.         c=x->left;
  186.         d=x->right;
  187.         z->right=b;
  188.         if (b) b->parent=z;
  189.         z->parent=y;
  190.         y->left=z;
  191.         y->right=c;
  192.         if (c) c->parent=y;
  193.         y->parent=x;
  194.         x->left=y;
  195.         if (zz) {
  196.             if (zz->left==z){
  197.              zz->left=x;
  198.             }
  199.             else{
  200.              zz->right=x;
  201.             }
  202.         }
  203.         else { 
  204.             x->successor=z->successor;
  205.             z->successor=0;
  206.         }
  207.         x->parent=zz;
  208.         
  209.         mincost_a = (a) ? a->dmin + z->dmin : BIG;
  210.         mincost_b = (b) ? b->dmin + y->dmin + z->dmin : BIG;
  211.         mincost_c = (c) ? c->dmin + x->dmin + y->dmin + z->dmin : BIG;
  212.         mincost_d = (d) ? d->dmin + x->dmin + y->dmin + z->dmin : BIG;
  213.         mincost_x =     x->dmin + y->dmin + z->dmin;
  214.         mincost_y =     y->dmin + z->dmin;
  215.         mincost_z =     z->dmin;
  216.         cost_x     = mincost_x + x->dcost;
  217.         cost_y     = mincost_y + y->dcost;
  218.         cost_z     = mincost_z + z->dcost;
  219.         
  220.         mincost_x = mincost_z;
  221.         mincost_z = (mincost_a <= mincost_b) ? mincost_a : mincost_b;
  222.         if (cost_z <= mincost_z) mincost_z = cost_z;
  223.         mincost_y = (mincost_c <= mincost_z) ? mincost_c : mincost_z;
  224.         if (cost_y <= mincost_y) mincost_y = cost_y;
  225.         x->dcost = cost_x - mincost_x;
  226.         y->dcost = cost_y - mincost_y;
  227.         z->dcost = cost_z - mincost_z;
  228.         x->dmin = mincost_x;
  229.         y->dmin = mincost_y - mincost_x;
  230.         z->dmin = mincost_z - mincost_y;
  231.         if (a) a->dmin    = mincost_a - mincost_z;
  232.         if (b) b->dmin    = mincost_b - mincost_z;
  233.         if (c) c->dmin    = mincost_c - mincost_y;
  234.         if (d) d->dmin    = mincost_d - mincost_x;
  235.  
  236.         continue;
  237.       }
  238.       
  239.  
  240.       // 3.Fall: x linkes, p(x) rechtes Kind (oder umgekehrt)
  241.       // Zuerst x links, p(x) rechts:
  242.       
  243.       if ((z->right==y)&&(y->left==x)){   // (5)
  244.         a=z->left;
  245.         b=x->left;
  246.         c=x->right;
  247.         d=y->right;
  248.         z->right=b;
  249.         if (b) b->parent=z;
  250.         z->parent=x;
  251.         x->left=z;
  252.         y->left=c;
  253.         if (c) c->parent=y;
  254.         y->parent=x;
  255.         x->right=y;
  256.         if (zz) {
  257.             if (zz->left==z){
  258.              zz->left=x;
  259.             }
  260.             else{
  261.              zz->right=x;
  262.             }
  263.         } 
  264.         else {
  265.             x->successor=z->successor;
  266.             z->successor=0;
  267.         }
  268.         x->parent=zz;
  269.         
  270.         mincost_a = (a) ? a->dmin + z->dmin : BIG;
  271.         mincost_b = (b) ? b->dmin + x->dmin + y->dmin + z->dmin : BIG;
  272.         mincost_c = (c) ? c->dmin + x->dmin + y->dmin + z->dmin : BIG;
  273.         mincost_d = (d) ? d->dmin + y->dmin + z->dmin : BIG;
  274.         mincost_x =     x->dmin + y->dmin + z->dmin;
  275.         mincost_y =     y->dmin + z->dmin;
  276.         mincost_z =     z->dmin;
  277.         cost_x     = mincost_x + x->dcost;
  278.         cost_y     = mincost_y + y->dcost;
  279.         cost_z     = mincost_z + z->dcost;
  280.         
  281.         mincost_x = mincost_z;
  282.         mincost_z = (mincost_a <= mincost_b) ? mincost_a : mincost_b;
  283.         if (cost_z <= mincost_z) mincost_z = cost_z;
  284.         mincost_y = (mincost_c <= mincost_d) ? mincost_c : mincost_d;
  285.         if (cost_y <= mincost_y) mincost_y = cost_y;
  286.         x->dcost = cost_x - mincost_x;
  287.         y->dcost = cost_y - mincost_y;
  288.         z->dcost = cost_z - mincost_z;
  289.         x->dmin = mincost_x;
  290.         y->dmin = mincost_y - mincost_x;
  291.         z->dmin = mincost_z - mincost_x;
  292.         if (a) a->dmin    = mincost_a - mincost_z;
  293.         if (b) b->dmin    = mincost_b - mincost_z;
  294.         if (c) c->dmin    = mincost_c - mincost_y;
  295.         if (d) d->dmin    = mincost_d - mincost_y;
  296.  
  297.         continue;
  298.       }
  299.  
  300.       
  301.       // Nun x rechts, p(x) links:
  302.       
  303.       if ((z->left==y)&&(y->right==x)){    // (6)
  304.         a=y->left;
  305.         b=x->left;
  306.         c=x->right;
  307.         d=z->right;
  308.         y->right=b;
  309.         if (b) b->parent=y;
  310.         y->parent=x;
  311.         x->left=y;
  312.         z->left=c;
  313.         if (c) c->parent=z;
  314.         z->parent=x;
  315.         x->right=z;
  316.         if (zz) {
  317.             if (zz->left==z){
  318.              zz->left=x;
  319.             }
  320.             else{
  321.              zz->right=x;
  322.             }
  323.         }
  324.         else {
  325.             x->successor=z->successor;
  326.             z->successor=0;
  327.         }
  328.         x->parent=zz;
  329.         
  330.         mincost_a = (a) ? a->dmin + y->dmin + z->dmin : BIG;
  331.         mincost_b = (b) ? b->dmin + x->dmin + y->dmin + z->dmin : BIG;
  332.         mincost_c = (c) ? c->dmin + x->dmin + y->dmin + z->dmin : BIG;
  333.         mincost_d = (d) ? d->dmin + z->dmin : BIG;
  334.         mincost_x =     x->dmin + y->dmin + z->dmin;
  335.         mincost_y =     y->dmin + z->dmin;
  336.         mincost_z =     z->dmin;
  337.         cost_x     = mincost_x + x->dcost;
  338.         cost_y     = mincost_y + y->dcost;
  339.         cost_z     = mincost_z + z->dcost;
  340.         
  341.         mincost_x = mincost_z;
  342.         mincost_z = (mincost_c <= mincost_d) ? mincost_c : mincost_d;
  343.         if (cost_z <= mincost_z) mincost_z = cost_z;
  344.         mincost_y = (mincost_a <= mincost_b) ? mincost_a : mincost_b;
  345.         if (cost_y <= mincost_y) mincost_y = cost_y;
  346.         x->dcost = cost_x - mincost_x;
  347.         y->dcost = cost_y - mincost_y;
  348.         z->dcost = cost_z - mincost_z;
  349.         x->dmin = mincost_x;
  350.         y->dmin = mincost_y - mincost_x;
  351.         z->dmin = mincost_z - mincost_x;
  352.         if (a) a->dmin    = mincost_a - mincost_y;
  353.         if (b) b->dmin    = mincost_b - mincost_y;
  354.         if (c) c->dmin    = mincost_c - mincost_z;
  355.         if (d) d->dmin    = mincost_d - mincost_z;
  356.  
  357.       }
  358.      }
  359. }
  360.  
  361.  
  362. d_vertex dyna_trees::assemble(d_vertex u, d_vertex v, d_vertex w)
  363. {
  364.      double mincost_u,
  365.         mincost_v,
  366.         mincost_w,
  367.         cost_v;
  368.  
  369.      v->left=u;
  370.      v->right=w;
  371.      if (u) u->parent=v;
  372.      if (w) w->parent=v;
  373.      
  374.      mincost_u = (u) ? u->dmin : BIG;
  375.      mincost_v =       v->dmin;
  376.      mincost_w = (w) ? w->dmin : BIG;
  377.      cost_v = mincost_v + v->dcost;
  378.      
  379.      mincost_v = (mincost_u <= mincost_w) ? mincost_u : mincost_w;
  380.      if (cost_v < mincost_v) mincost_v = cost_v;
  381.      v->dcost = cost_v - mincost_v;
  382.      v->dmin = mincost_v;
  383.      if (u) u->dmin = mincost_u - mincost_v;
  384.      if (w) w->dmin = mincost_w - mincost_v;
  385.  
  386.      return v;
  387. }
  388.  
  389.  
  390. void   dyna_trees::disassemble(d_vertex v, d_vertex& v1, d_vertex& v2) {
  391.      double mincost_v1,
  392.         mincost_v2;
  393.  
  394.  
  395.      v1=v->left;
  396.      v2=v->right;
  397.      if (v1) v1->parent=0;
  398.      if (v2) v2->parent=0;
  399.      v->left=0;
  400.      v->right=0;
  401.  
  402.      mincost_v1 = (v1) ? v1->dmin + v->dmin : BIG;
  403.      mincost_v2 = (v2) ? v2->dmin + v->dmin : BIG;
  404.  
  405.      if (v1) v1->dmin = mincost_v1;
  406.      if (v2) v2->dmin = mincost_v2;
  407.      
  408.      v->dmin += v->dcost;
  409.      v->dcost = 0;
  410. }
  411.  
  412.  
  413. d_vertex dyna_trees::makepath(void* i)
  414. {
  415.      if (first==0) {
  416.       first=last=new d_node(i);
  417.      }
  418.      else {
  419.       last->next=new d_node(i);
  420.       last=last->next;
  421.      }
  422.      return last;
  423. }
  424.  
  425.  
  426. d_vertex dyna_trees::findpath(d_vertex v)
  427. {
  428.      splay(v);
  429.      return v;
  430. }
  431.  
  432.  
  433.  
  434. d_vertex dyna_trees::findpathcost(d_path p, double& d)
  435. {
  436.      d_vertex w;
  437.      w=p;
  438.      
  439.      while( !( (w->dcost==0) && ( (w->right==0)||(w->right->dmin>0) ) ) ) {
  440.       if (w->right) {
  441.         if (w->right->dmin == 0) {
  442.              w=w->right;
  443.         } else {
  444.              if (w->dcost>0) w=w->left;
  445.         }  
  446.       }
  447.       else {
  448.         if (w->dcost>0) w=w->left;
  449.       }
  450.      }
  451.      splay(w);
  452.      d=w->dmin;
  453.      return w;
  454. }
  455.  
  456.  
  457.  
  458. d_vertex dyna_trees::findtail(d_path p)
  459. {
  460.      d_vertex w;
  461.      w=p;
  462.      
  463.      while(w->right) {
  464.       w=w->right;
  465.      }
  466.      splay(w);
  467.      return w;
  468. }
  469.  
  470.  
  471.  
  472. void dyna_trees::addpathcost(d_path p, double x)
  473. {
  474.      p->dmin += x;
  475. }
  476.  
  477.  
  478.  
  479. d_vertex dyna_trees::join(d_path p, d_path v, d_path q)
  480. {
  481.      return assemble(p, v, q);
  482. }
  483.  
  484.  
  485.  
  486. void dyna_trees::split(d_vertex v, d_vertex& v1, d_vertex& v2)
  487. {
  488.      splay(v);
  489.      disassemble(v, v1, v2);
  490. }
  491.  
  492.  
  493.  
  494. d_path dyna_trees::expose(d_vertex v)
  495. {
  496.      d_path   p,
  497.           q,
  498.           r;
  499.      d_vertex w;
  500.      
  501.      p=0;
  502.      while (v) {
  503.       w=findpath(v)->successor;
  504.       split(v,q,r);
  505.       if (q) q->successor=v;
  506.       p=join(p, v, r);
  507.       v=w;
  508.      }
  509.      p->successor=0;
  510.      return p;
  511. }
  512.  
  513.  
  514. d_vertex dyna_trees::maketree(void* i)
  515. {
  516.      copy_inf(i);
  517.  
  518.      d_vertex v;
  519.      v=makepath(i);
  520.      v->successor=0;
  521.      return v;
  522. }
  523.  
  524.  
  525. d_vertex dyna_trees::findroot(d_vertex v)
  526. {
  527.      return findtail(expose(v));
  528. }
  529.  
  530.  
  531.  
  532. d_vertex dyna_trees::findcost(d_vertex v, double& d)
  533. {
  534.      return findpathcost(expose(v),d);
  535. }
  536.  
  537.  
  538.  
  539. void dyna_trees::addcost(d_vertex v, double x)
  540. {
  541.      addpathcost(expose(v),x);
  542. }
  543.  
  544.  
  545.  
  546. void dyna_trees::link(d_vertex v, d_vertex w)
  547. {
  548.      join( (d_vertex) 0, expose(v), expose(w) )->successor=0;
  549. }
  550.  
  551.  
  552.  
  553. void dyna_trees::cut(d_vertex v) 
  554. {
  555.      d_path p,q;
  556.      
  557.      expose(v);
  558.      split(v,p,q);
  559.      v->successor=q->successor=0;
  560. }
  561.  
  562.  
  563.  
  564. dyna_trees::~dyna_trees()
  565. {
  566.      d_node *x, 
  567.         *y;
  568.       
  569.      x=first;
  570.      while(x) {
  571.       y=x->next;
  572.       delete x;
  573.       x=y;
  574.      }
  575. }
  576.  
  577.  
  578.  
  579.